package znet

import (
	"bytes"
	"encoding/binary"
	"github.com/pkg/errors"
	"my-zinx/ziface"
)

type DataPack struct{}

func (d DataPack) GetHeadLen() uint64 {
	// DataLen uint64 + ID uint64
	return 16
}

func (d DataPack) Pack(msg ziface.IMessage) ([]byte, error) {
	buf := bytes.NewBuffer([]byte{})

	// 小端模式 写字节流
	if err := binary.Write(buf, binary.LittleEndian, msg.GetDataLen()); err != nil {
		return nil, err
	}

	if err := binary.Write(buf, binary.LittleEndian, msg.GetMsgID()); err != nil {
		return nil, err
	}

	if err := binary.Write(buf, binary.LittleEndian, msg.GetData()); err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

// Unpack 解包：只读取DataLen和MsgID，后根据DataLen获取Data
func (d DataPack) Unpack(data []byte) (ziface.IMessage, error) {
	msg := NewEmptyMessage()

	buf := bytes.NewReader(data)

	if err := binary.Read(buf, binary.LittleEndian, &msg.DataLen); err != nil {
		return nil, err
	}

	if err := binary.Read(buf, binary.LittleEndian, &msg.ID); err != nil {
		return nil, err
	}

	// 判断是否合法
	if !msg.IsValidMessage() {
		return nil, errors.New("Msg data is too large")
	}

	return msg, nil
}

func NewDataPack() *DataPack {
	return &DataPack{}
}
